(defun my-prop (x)
  (let* (
         (x-values (REMOVE-DUPLICATES x))
         (x-dim (length x-values))
         (x-freq (mapcar #'(lambda (y) (count y x)) x-values))
         (x-percent (* 100 (/ (mapcar #'(lambda (y) (count y x)) x-values) 
               (length x))))
         
         (table (transpose (make-array (list 3 x-dim) :initial-contents 
                                       (combine x-values x-freq x-percent))))
         )
    (sort-and-permute (first (column-list table)) table)
    )
   )

(defmeth reliability-model-object-proto :Report
  (&key (stream t) 
        (dialog nil))
  (if (not (eq current-object self)) (setcm self))
  (let* ((w nil)
         (data (send self :data))         
         (item-freq (mapcar #'(lambda (x) (my-prop (combine x))) (column-list data)))
         (item-values (mapcar #'(lambda (x) (map-elements 'NUM-TO-STRINg (combine (first (column-list x))))) item-freq))
         (number-of-values (mapcar #'(lambda (x) (length x)) item-values))
         (tables  (mapcar #'(lambda (x y) (transpose (make-array (list 2 y) :initial-contents (combine 
                                        (second (column-list x)) (third (column-list x)))))) item-freq number-of-values))
         (dialog-value (send self :dialog-value))
         (n-items (send self :n-items))
         (scale (send self :scale))
         (scale-if (send self :scale-if))
         (item-labels (send self :variables))
         (descriptive-labels (list "Mean" "Var" "StDd" "Skewness" "Kurtosis"))
         (alfa-labels (list "Mean-if" "Var-if""StDd-if" "Skew-if" "Kurt-if" "Alpha-if"))
         (kuder-labels (list "Mean-if" "Var-if""StDd-if" "Skew-if" "Kurt-if" "KR20-if"))
         (nobs (send self :nobs))
         (control-dicotomico dialog-value)
         (item-matrix (transpose (make-array (list 5 n-items) :initial-contents (combine (send self :item-means) (send self :item-variances) (send self :item-std) (send self :item-skewness) (send self :item-kurtosis)))))
         (scale-descriptive (transpose (make-array '(5 1) :initial-contents (combine (send self :scale-mean)(send self :scale-variance)(send self :scale-std)(send self :scale-skewness)(send self :scale-kurtosis)))))
         (scale-fivnum (transpose (make-array '(5 1) :initial-contents (combine (fivnum scale)))))
         (fivnum-labels (list "Minimun" "1stQ" "Median" "3rdQ" "Maximun"))
         (scale-deciles (transpose (make-array '(1 9) :initial-contents (combine(quantile scale '(.1 .2 .3 .4 .5 .6 .7 .8 .9))))))
         (deciles-labels (mapcar #'(lambda (x) (format nil "Dec~a" x)) (iseq 1 9)))
         (percent (/ (iseq 1 99) (repeat 100 99)))
         (scale-percent (transpose (make-array '(1 99) :initial-contents (combine(quantile scale percent)))))
(percent-labels (mapcar #'(lambda (x) (format nil "Perc~a" x)) (iseq 1 99)))

         (alfa-report (transpose (make-array (list 6 n-items) :initial-contents (combine (send self :scale-mean-if) (send self :scale-variance-if)(send self :scale-std-if)(send self :scale-skewness-if) (send self :scale-kurtosis-if)(send self :alfa-if)) )))
          (alfa (send self :alfa))

    ;;; 95% CI and p-value for alfa 
         (fa (f-quant .975 (- nobs 1) (* (- nobs 1) (- n-items 1))))
         (fb (f-quant .025 (- nobs 1) (* (- nobs 1) (- n-items 1)))) 
         (inf-alfa (-  1 (* (- 1 alfa ) fa)))
         (sup-alfa (-  1 (* (- 1 alfa ) fb)))
         (p-value-for-alfa (f-cdf  (f-dens (- 1 alfa) (- nobs 1) (* (- nobs 1) (- n-items 1))) (- nobs 1) (* (- nobs 1) (- n-items 1))))

         (item-correlation-matrix (correlation-matrix data))
         (average-correlation (/ (- (sum (abs item-correlation-matrix)) n-items) ( - (* n-items n-items) n-items)))

         (r-item-scale (make-array (list n-items 1) :initial-contents (mapcar #'(lambda (x) (correlation x scale)) (column-list  data))))
         (r-item-scale-if (make-array (list n-items 1) :initial-contents  (mapcar #'(lambda (x y) (correlation x y)) scale-if (column-list  data))))
         
         (scale-pares (send self :scale-pares))
         (scale-impares (send self :scale-impares))
         (scales (make-array (list 2 nobs) :initial-contents  (combine   scale-pares scale-impares )))
         (scales-matrix (transpose (make-array (list 5 2) :initial-contents (combine (mapcar #'mean (row-list scales)) (mapcar #'variance (row-list scales)) (mapcar #'skewness (row-list scales)) (mapcar #'standard-deviation (row-list scales)) (mapcar #'kurtosis (row-list scales))))))
          (split-half (send self  :Split-Half))
         (unequal-split (send self  :unequal-split))
         (guttman (send self  :guttman))
         (r-halfs (correlation scale-pares scale-impares))
         (theta (send self :theta))
         (eign (send self :eign))
         (eigenvalues (send self :eigenvalues))
         (pa-result (transpose (make-array (list 2 n-items ) :initial-contents (list (send self :eigenvalues) (send self :pa-eigen)))))
         (Eig-Labels (mapcar #'(lambda (x) (format nil " Eigenvalue~a  " x))(+ 1 (iseq n-items))))
         ;(Axis-Labels (mapcar #'(lambda (x) (format nil "Factor~a  " x)) (+ 1 (iseq (length (send self :e-axis))))))
         (stand-error (* (send self :scale-std) (sqrt (- 1 alfa))))
         (stand-error-Spearman (* (send self :scale-std) (sqrt (- 1 split-half))))
         (stand-error-theta (* (send self :scale-std) (sqrt (- 1 theta))))

         (stand-estim (* (send self :scale-std) (* (sqrt (- 1 alfa)) (sqrt alfa))))
         (stand-estim-Spearman (* (send self :scale-std) (* (sqrt (- 1 split-half)) (sqrt split-half))))
         (stand-estim-theta (* (send self :scale-std) (* (sqrt (- 1 theta)) (sqrt theta))))
         
         (pq (cond 
      ((= control-dicotomico 6)
          (transpose (make-array (list 2 n-items) :initial-contents (combine (send self  :p)(send self  :q)))))
           (t nil)))     
         

         (kuder (cond 
      ((= control-dicotomico 6) (send self :kuder))
                  (t nil)))
     (stand-error-kr20 (cond 
      ((= control-dicotomico 6) (* (send self :scale-std) (sqrt (- 1 theta))))
                  (t nil)))

         (kuder-report (cond 
      ((= control-dicotomico 6)(transpose (make-array (list 6 n-items) :initial-contents (combine (send self :scale-mean-if) (send self :scale-variance-if) (send self :scale-std-if) (send self :scale-skewness-if)  (send self :scale-kurtosis-if)(send self :kuder-if)))))
                  (t nil)))



(r-bis-item-scale (cond ((= control-dicotomico 6) (make-array (list n-items 1) :initial-contents (send self :point-bis-corr))) 
                  (t nil)))

(corrected-r-bis-item-scale (cond ((= control-dicotomico 6) (make-array (list n-items 1) :initial-contents (send self :corrected-point-bis-corr)))    (t nil)))
 

         (report-dialog 
          (cond 
            
            ((= dialog-value 0) 
           (setf Choice0 (choose-subset-dialog
                  "Item descrptive analysis Report"
                 '("Frecuency tables"
                  "Descriptives"
                  "Inter-item Correlations"))))

            ((= dialog-value 1) 
           (setf Choice1 (choose-subset-dialog
               "Test descrptive analysis Report"
               '("Descriptives for total test score"
                 "Decile and percentil values"))))
           
            ((= dialog-value 2) 
           (setf Choice2 (choose-subset-dialog
               "Item-Test analysis Report"
               '("Descriptive if item deleted"
                 "Item-Test correlation"))))

            ((= dialog-value 3) 
           (setf Choice3 (choose-subset-dialog
               "Cronbach's Alpha Report"
                          '("Cronbach's Alpha and SEM"
                            "Cronbach's Alpha if item deletd"))))
 ((= dialog-value 4)
            (setf Choice4 
              (choose-subset-dialog
               "Split-half Report"
               '("Descriptive for test halves"
                 "Split-half coefficients"))))            

          

            ((= dialog-value 5) 
             (setf Choice5
              (choose-subset-dialog
               "Theta Report"
               '("Theta Report"
                 "Parallel Analysis"       
                 ))))

            ((= dialog-value 6) 
             (setf Choice6
              (choose-subset-dialog
               "Binary Item Report"
               '("Descriptive"
                 "KR20"       
                 "Point Biserial Correlation"
                 ))))
            )
          )
         )

(cond 

  ;;;**ITEM DESCIPTIVE REPORT
  ((= dialog-value 0)    
   (when choice0 (setf w (report-header (send self :title "Item Descriptive Analysis"))))
   (display-string
    (format nil "~%___________________________________________________________________~2%                 ITEM DESCRIPTIVE ANALYSIS~2% ~2%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
   (display-string (format nil "~%Number of observations: ~a" nobs) w)
   (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
   (display-string
    (format nil "Item labels: ~a~%" item-labels ) w)

   (when (member '0 (select Choice0 0))                
         (display-string
          (format nil "~%___________________________________________________________________~2%                     * Frecuency tables for Items * ~%___________________________________________________________________~%") w)

         (mapcar #'(lambda (x y z)
                     (print-matrix-to-window  x w :row-heading y :column-heading "" :row-labels z  :column-labels (list "Freq" "Percent")  :decimals 2)) tables  item-labels item-values)
                )

   (when (member '1 (select Choice0 0))
         (display-string
          (format nil "~%___________________________________________________________________~2%                     * Descriptive for Items * ~%___________________________________________________________________~%") w)

         (print-matrix-to-window  item-matrix
          w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels descriptive-labels :decimals 3)         
                )
   
   (when (member '2 (select Choice0 0))
         (display-string
          (format nil "~%___________________________________________________________________~2%                   *  Inter-item correlations * ~%___________________________________________________________________~%") w)

         (print-matrix-to-window  item-correlation-matrix
          w :row-heading "" :column-heading "" :row-labels item-labels :column-labels item-labels :decimals 2)
         (display-string (format nil "~%Average inter-item correlation (absolute value): ~0,3f~%" average-correlation) w))                         
   )


;;;**TEST SCORE DESCRIPTIVE REPORT
  ((= dialog-value 1) 
   (when Choice1
         (setf w (report-header (send self :title "Test score descriptive Report"))))
   (display-string
    (format nil "~%___________________________________________________________________~2%                TEST SCORE DESCRIPTIVE ANALYSIS~%                ~%~%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
   (display-string (format nil "~%Number of observations: ~a" nobs) w)
   (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
   (display-string
    (format nil "Item labels: ~a~%" item-labels ) w)
          
   (when (member '0 (select Choice1 0)) 
         (display-string
          (format nil "~%___________________________________________________________________~2%                     * Descriptives for Test Scores* ~%___________________________________________________________________~%") w)
         (display-string
          (format nil "~%Moments:") w)               
         (print-matrix-to-window scale-descriptive w :column-heading "" :row-heading nil :row-labels (list "")  :column-labels descriptive-labels :decimals 3)
                (display-string
                 (format nil "~%Min, Max, Quartiles:") w)
                (print-matrix-to-window scale-fivnum      w :column-heading "" :row-heading nil :row-labels (list "") :column-labels fivnum-labels :decimals 3)
                )

   (when (member '1 (select Choice1 0))
         (display-string
          (format nil "~%___________________________________________________________________~2%                    * Decile and percentile values * ~%___________________________________________________________________~%") w)

         (display-string
          (format nil "~%Deciles:") w)
         (print-matrix-to-window scale-deciles    w :column-heading "" :row-heading nil :row-labels deciles-labels :column-labels (list "Score") :decimals 2)
         (display-string
          (format nil "~%Percentiles:") w)
         (print-matrix-to-window scale-percent    w :column-heading "" :row-heading nil :row-labels percent-labels :column-labels (list "Score") :decimals 2)
                )
    )

;**ITEM-TEST ANALYSIS REPORT
  ( (= dialog-value 2)
    (when Choice2
          (setf w (report-header (send self :title "Item-test analysis Report"))))
    (display-string
     (format nil "~%___________________________________________________________________~2%           * ITEM-TEST ANALYSIS REPORT * ~%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
    (display-string (format nil "~%Number of observations: ~a" nobs) w)
    (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
    (display-string
     (format nil "Item labels: ~a~%" item-labels ) w)

    (when (member '0 (select Choice2 0))
          (display-string
           (format nil "~%___________________________________________________________________~2%                      * Descriptive if Item deleted * ~%___________________________________________________________________~2%Descriptive and Cronbach's Alpha if item deleted.~%") w)
          (print-matrix-to-window  alfa-report            w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels alfa-labels :decimals 3))

    (when (member '1 (select Choice2 0))
          (display-string
           (format nil "~%___________________________________________________________________~2%                      * Item-test correlation * ~%___________________________________________________________________~%") w)
 
          (display-string (format nil "~%Item-total correlation: ~%") w)
          (print-matrix-to-window  r-item-scale
          w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels (list "") :decimals 3)


          (display-string (format nil "~%Corrected Item-total correlation: ~%") w)
          (print-matrix-to-window  r-item-scale-if
          w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels (list "") :decimals 3))
                )
   
 ;**ALPHA REPORT
  ((= dialog-value 3)
   (when Choice3
         (when choice3 (setf w (report-header (send self :title "Cronbach's Alpha Report"))))
         (display-string
          (format nil "~%___________________________________________________________________~2%                 CRONBACH'S ALPHA REPORT~2%     Cronbach's Alpha for reliability analysis of sum scale~2%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
         (display-string (format nil "~%Number of observations: ~a" nobs) w)
         (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
         (display-string
          (format nil "Item labels: ~a~%" item-labels ) w)

         (when (member '0 (select Choice3 0))
               (display-string
                (format nil "~%___________________________________________________________________~2%                        * Alpha Report * ~%___________________________________________________________________~%") w)
               (display-string (format nil "~%Cronbach's Alpha: ~0,3f" alfa) w)
               (display-string (format nil "~%95% Confidence Interval for Alpha:  ~0,3f,~0,3f~%" inf-alfa sup-alfa) w)               
               (display-string (format nil "~%Standard error of measurement based on Alpha: ~0,3f" stand-error) w)
               (display-string (format nil "~%Standard error of estimation based on Alpha: ~0,3f~%" stand-estim)   w)
               )

         (when (member '1 (select Choice3 0))
               (display-string
                (format nil "~%___________________________________________________________________~2%                      * If Item deleted * ~%___________________________________________________________________~2%Descriptive and Cronbach's Alpha for if item deleted.~%") w)
               (print-matrix-to-window  alfa-report            w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels alfa-labels :decimals 3))         
           )
  )

;**SPLIT-REPORT
  ((= dialog-value 4) 
(when Choice4
          (setf w (report-header (send self :title "Split-Half Report"))))
          (display-string
           (format nil "~%___________________________________________________________________~2%                SPLIT-HALF REPORT~% ~%~%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
       (display-string (format nil "~%Number of observations: ~a" nobs) w)
       (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
       (display-string
           (format nil "Item labels: ~a~%" item-labels ) w)
                   
          (when (member '0 (select Choice4 0))
                (display-string
          (format nil "~%___________________________________________________________________~2%                    * Descriptive for Test halves * ~%___________________________________________________________________~%") w)
(display-string (format nil "~%Number of items in part one: ~a" (length (send self :pares)))  w)
(display-string (format nil "~%Number of items in part two: ~a~%" (length (send self :impares))) w)

                   (print-matrix-to-window scales-matrix  w :column-heading "" :row-heading "" :row-labels (list "Half-even" "Half-odd"):column-labels descriptive-labels :decimals 3)
                )

  (when (member '1 (select Choice4 0))
                (display-string
                 (format nil "~%___________________________________________________________________~2%                      * Split-Half Report * ~%___________________________________________________________________~%") w)


(display-string (format nil "~%Correlation between halves: ~0,3f" r-halfs) w)
(display-string (format nil "~%Equal-length Spearman-Brown: ~0,3f" split-half) w)
(display-string (format nil "~%Unequal-length Spearman-Brown: ~0,3f" unequal-split) w)
(display-string (format nil "~%Guttman-Flanagan Split-half: ~0,3f~%" guttman) w)
 (display-string (format nil "~%Standard error of measurement based on Spearman-Brown: ~0,3f" stand-error-spearman) w)
(display-string (format nil "~%Standard error of estimation based on Spearman-Brown: ~0,3f~%" stand-estim-spearman)   w)
        )
   )

;;**THETA REPORT
  ( (= dialog-value 5)
    (when Choice5
          (setf w (report-header (send self :title "Theta Report"))))
    (display-string
     (format nil "~%___________________________________________________________________~2%           * THETA COEFFICIENT BASED ON FIRST PCA EIGENVALUE * ~%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
    (display-string (format nil "~%Number of observations: ~a" nobs) w)
    (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
    (display-string
           (format nil "Item labels: ~a~%" item-labels ) w)

    (when (member '0 (select Choice5 0))
          (display-string
                 (format nil "~%___________________________________________________________________~2%                      * Theta Report * ~%___________________________________________________________________~%") w)

          (display-string (format nil "~%Theta value: ~0,3f" theta) w)
          (display-string (format nil "~%First PCA eigenvalue: ~0,3f~%" eign) w)
          (display-string  (format nil "~%Standard error of measurement based on Theta : ~0,3f" stand-error-theta) w)
          (display-string (format nil "~%Standard error of estimation based on Theta: ~0,3f~%" stand-estim-theta)   w)
                )
    (when (member '1 (select Choice5 0))              
          (display-string
           (format nil "~%Parallel Analysis~%") w)
          (print-matrix-to-window  pa-result   w :row-heading "" :column-heading "" :row-labels Eig-Labels :column-labels (list "Obs-eigen" "Est-eigen") :decimals 3)
          )    
    )

;******Binary Item
((= dialog-value 6)
(when Choice6
          (setf w (report-header (send self :title "Binary Item Report"))))
          (display-string
           (format nil "~%___________________________________________________________________~2%                      BINARY ITEM REPORT~2%___________________________________________________________________~2%MODEL: ~a" (send self :name)) w)
       (display-string (format nil "~%Number of observations: ~a" nobs) w)
       (display-string (format nil "~%Number of Items: ~a~%" n-items) w)
       (display-string
           (format nil "Item labels: ~a~%" item-labels ) w)

          (when (member '0 (select Choice6 0))
 (display-string
                 (format nil "~%___________________________________________________________________~2%                       * Descriptive * ~%___________________________________________________________________~2%") w)

                (print-matrix-to-window  pq
          w :row-heading "Items" :column-heading "" :row-labels item-labels  :column-labels (list "p" "q") :decimals 2)

                (print-matrix-to-window scale-descriptive  w  :column-heading "" :row-heading nil :row-labels (list "Scale:") :column-labels descriptive-labels :decimals 3))

          (when (member '1 (select Choice6 0))
                (display-string
                 (format nil "~%___________________________________________________________________~2%                   * Kuder-Richardson20 * ~%___________________________________________________________________~2%") w)
                (display-string (format nil "~%Kuder-Richardson20: ~0,3f~%" alfa) w)


                (display-string (format nil "~%Standard error of measurement based on KR20: ~0,3f" stand-error) w)
               (display-string (format nil "~%Standard error of estimation based on KR20: ~0,3f~%" stand-estim)   w)

                 (display-string
          (format nil "~%___________________________________________________________________~2%                      * If Item deleted * ~%___________________________________________________________________~2%Descriptive and KR20 for scale if item deleted.~%") w)
                (print-matrix-to-window  alfa-report  w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels kuder-labels :decimals 3))
 
 
 
 (when (member '2 (select Choice6 0))
        (display-string
                 (format nil "~%___________________________________________________________________~2%                   * Point-Biserial Correlation * ~%___________________________________________________________________~2%") w)
                (print-matrix-to-window  r-bis-item-scale          w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels (list "") :decimals 3)


        (display-string
                 (format nil "~%___________________________________________________________________~2%                   * Corrected-Point-Biserial Correlation * ~%___________________________________________________________________~2%") w)
                (print-matrix-to-window  corrected-r-bis-item-scale          w :row-heading "Items" :column-heading "" :row-labels item-labels :column-labels (list "") :decimals 3))
 )
  
  )
    (send w :fit-window-to-text)
    )    
  
  
  )
                                                                                                                                                                                                                                                            (require (strcat "rel-vis.lsp"))
                                                                                                                                                                                                                                                            